//函数柯里化
//实现一个add方法 add(1)(2)(3)=6 add(1,2,3)(4)=10


// function add() {
//     const args = Array.prototype.slice.call(arguments)
//     const inner = function () {
//         args.push(...arguments)
//         return inner
//     }
//     inner.toString = function () {
//         const sum = args.reduce((pre, cur) => {
//             return pre + cur
//         }, 0)
//         return sum
//     }

//     return inner
// }
// function add(...args) {
//     let allArgs = [...args];
//     function fn(...newArgs) {
//         allArgs = [...allArgs, ...newArgs];
//         return fn;
//     }
//     fn.toString = function () {
//         if (!allArgs.length) {
//             return;
//         }
//         let res = 0
//         allArgs.reduce((sum, cur) => res = sum + cur);
//         return res
//     };
//     return fn;
// }
// console.log(add(1)(2)(3).toString());


//参数不固定


function add(...args) {
    //求和
    return args.reduce((a, b) => a + b)
}
function currying(fn) {
    let args = []
    return function temp(...newArgs) {
        if (newArgs.length) {
            args = [
                ...args,
                ...newArgs
            ]
            return temp
        } else {
            let val = fn.apply(this, args)
            args = [] //保证再次调用时清空
            return val
        }
    }
}
// let addCurry = currying(add)
// console.log(addCurry(1)(2)(3)(4, 5)())  //15
// console.log(addCurry(1)(2)(3, 4, 5)())  //15
// console.log(addCurry(1)(2, 3, 4, 5)())  //15


//另外一种写法
function curry(fn) {
    const fnArgsLength = fn.length // 传入函数的参数长度
    let args = []

    // ts 中，独立的函数，this 需要声明类型
    function calc(...newArgs) {
        // 积累参数
        args = [
            ...args,
            ...newArgs
        ]
        if (args.length < fnArgsLength) {
            // 参数不够，返回函数
            return calc
        } else {
            // 参数够了，返回执行结果
            return fn.apply(this, args.slice(0, fnArgsLength))
        }
    }

    return calc
}

// function add(a: number, b: number, c: number): number {
//     return a + b + c
// }
// // add(10, 20, 30) // 60

// const curryAdd = curry(add)
// const res = curryAdd(10)(20)(30) // 60
// console.info(res)